﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Xml;

namespace GEAR_Structure
{
    [Serializable]
    public class Materiale
    {
        /// <summary>
        /// Proprietà che notifica la variazione di una variabile al fine del databuilding
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        protected void NotifyPropertyChanged(string name)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

        public enum typology_material { [EnumDescription("Intonaco")]plaster = 1, [EnumDescription("Sistema Costruttivo")] construction_system,[EnumDescription("Isolante Parete")] insulating_wall, [EnumDescription("Isolante Solaio")] insulating_floor, [EnumDescription("Solaio LateroCemento")] slab_bearing,[EnumDescription("Solaio in c.a.")] slab_ca, [EnumDescription("Strato Resiliente")] resilient_layer, [EnumDescription("Strato Omogeneo")] homogeneous_layer,[EnumDescription("Generico")] generic };
        
        typology_material typology;//tipologia del materiale
        string name;//nome del materiale
        double conductivity;//conducibilità termica del materiale [W/(mK)]
        double conduttance;//condutanza specifica dello strato di materiale [W/(m²K)]
        double tickness;//spessore del materile [m]
        bool conductivityEquivalent;//conducibilità termica equivalente del materiale non omogeneo [W/(mK)]
        double density;//densità o massa volumica del materiale [kg/m³]
        double specificheat;//calore specifico del materiale [J/(kgK)]
        double hygroscopicresistnacefactor;//fattore di resistenza igroscopiaca del materiale [adimensionale]
        double[] vaporpermeability;//permeabilità al vapore del materiale [kg/(msPa)]
        double dynamicstiffness;//rigidità dinamica del materiale [MN/m³]
        double thermal_diffusivity;//difusività termica [m²/s]
        double thermal_effusivity;//efusività termica [J/(K²s¹'²)]
        double surfaceMass;//massa superficiale dello strato di materiale [kg/m²]
        /// <summary>
        /// Massa superficiale dello strato di materiale [kg/m²]
        /// </summary>
        public double SurfaceMass
        {
            get {
                if (this.tickness != 0)
                    return UNI.Energy.UniEnIso6946.LayerSurfaceMass(this);

                else
                    return 0;
            
            }
            
        }
        /// <summary>
        /// difusività termica [m²/s] del materiale
        /// </summary>
        public double Thermal_diffusivity
        {
            get {

                if (this.specificheat != 0 && this.density != 0 && this.conductivity != 0)
                    return UNI.Energy.UniEnIso6946.thermal_diffusivity(this);

                else
                    return 0;
                }
            
        }
        /// <summary>
        /// efusività termica del materiale [J/(K²s¹'²)]
        /// </summary>
        public double Thermal_effusivity
        {
            get {

                if (this.specificheat != 0 && this.density != 0 && this.conductivity != 0)
                    return UNI.Energy.UniEnIso6946.thermal_effusivity(this);

                else
                    return 0;
                }
            
        }
        /// <summary>
        /// tipologia del materiale
      /// </summary>
        public typology_material Typology
        {
            get { return typology; }
            set 
            {
                typology = value;
                NotifyPropertyChanged("Typology");
            }
        }
        /// <summary>
        /// rigidità dinamica del materiale [N/m³]
        /// </summary>
        public double DynamicStiffness
        {
            get { return dynamicstiffness; }
            set
            {
                dynamicstiffness = value;
                NotifyPropertyChanged("DynamicStiffness");
            }
        }
        /// <summary>
        /// permeabilità al vapore del materiale [kg/(msPa)] [0]min50% [1]mag50%
        /// </summary>
        public double[] VaporPermeability
        {
            get { return vaporpermeability; }
            set 
            { 
                vaporpermeability = value;
                hygroscopicresistnacefactor = UNI.Energy.UniEnIso13788.fattore_resistenza_igroscopica(this);
                NotifyPropertyChanged("VaporPermeabilityMin");
                NotifyPropertyChanged("VaporPermeabilityMax");
                NotifyPropertyChanged("VaporPermeability");
                NotifyPropertyChanged("HygroscopicResistnaceFactor");
            }
        }
        /// <summary>
        /// permeabilità al vapore del materiale minore del 50% [kg/(msPa)]
        /// </summary>
        public double VaporPermeabilityMin
        {
            get { return vaporpermeability[0]; }
            set
            {
                vaporpermeability[0] = value;
                hygroscopicresistnacefactor = UNI.Energy.UniEnIso13788.fattore_resistenza_igroscopica(this);
                NotifyPropertyChanged("VaporPermeability");
                NotifyPropertyChanged("VaporPermeabilityMin");
                NotifyPropertyChanged("HygroscopicResistnaceFactor");
            }
        }
        /// <summary>
        /// permeabilità al vapore del materiale maggiore del 50% [kg/(msPa)]
        /// </summary>
        public double VaporPermeabilityMax
        {
            get { return vaporpermeability[1]; }
            set 
            {
                vaporpermeability[1]=value;
                hygroscopicresistnacefactor = UNI.Energy.UniEnIso13788.fattore_resistenza_igroscopica(this);
                NotifyPropertyChanged("VaporPermeability");
                NotifyPropertyChanged("VaporPermeabilityMax");
                NotifyPropertyChanged("HygroscopicResistnaceFactor");
            }
        }
        /// <summary>
        /// fattore di resistenza igroscopiaca del materiale [adimensionale]
        /// </summary>
        public double HygroscopicResistnaceFactor
        {
            get { return hygroscopicresistnacefactor; }
            set 
            { 
                hygroscopicresistnacefactor = value;
                vaporpermeability = UNI.Energy.UniEnIso13788.vapor_permeability(this);
                NotifyPropertyChanged("HygroscopicResistnaceFactor");
                NotifyPropertyChanged("VaporPermeabilityMin");
                NotifyPropertyChanged("VaporPermeabilityMax");
                NotifyPropertyChanged("VaporPermeability");
                
            }
        }
        /// <summary>
        /// calore specifico del materiale [J/(kgK)]
        /// </summary>
        public double SpecificHeat
        {
            get { return specificheat; }
            set 
            { 
                specificheat = value;
                NotifyPropertyChanged("SpecificHeat");
            }
        }
        /// <summary>
        /// densità o massa volumica del materiale [kg/m³]
        /// </summary>
        public double Density
        {
            get { return density; }
            set 
            { 
                density = value;
                NotifyPropertyChanged("Density");
            }
        }
        /// <summary>
        /// conducibilità termica equivalente del materiale non omogeneo [W/(mK)]
        /// </summary>
        public bool ConductivityEquivalent
        {
            get { return conductivityEquivalent; }
            set 
            { 
                conductivityEquivalent = value;
                NotifyPropertyChanged("ConductivityEquivalent");
            }
        }
        /// <summary>
        /// spessore del materile [m]
        /// </summary>
        public double Tickness
        {
            get { return tickness; }
            set 
            { 
                tickness = value;
                NotifyPropertyChanged("Tickness");
                if (conductivityEquivalent)
                    Conduttance = this.conduttance;
                else
                    Conductivity = this.conductivity;
            }
        }
        /// <summary>
        /// conducibilità termica del materiale [W/(mK)]
        /// </summary>
        public double Conductivity
        {
            get { return conductivity; }
            set 
            {
                if (!conductivityEquivalent)
                {
                    conductivity = value;
                    conduttance = UNI.Energy.UniEnIso6946.conductance(this);
                    NotifyPropertyChanged("Conductivity");
                    NotifyPropertyChanged("Conduttance");
                }
            }
        }
        /// <summary>
        /// condutanza specifica dello strato di materiale [W/(m²K)]
        /// </summary>
        public double Conduttance
        {
            get { return conduttance; }
            set 
            {
                if (conductivityEquivalent)
                {
                    conduttance = value;
                    conductivity = UNI.Energy.UniEnIso6946.conductivity_equivalent(this);
                    NotifyPropertyChanged("Conductivity");
                    NotifyPropertyChanged("Conduttance");
                }
            }
        }
        public string Name
        {
            get { return name; }
            set 
            { 
                name = value;
                NotifyPropertyChanged("Name");
            }
        }
        /// <summary>
        /// costruttore
        /// </summary>
        /// <param name="m">materiale</param>
        public Materiale(Materiale m)
        {
            this.typology=m.typology;
            this.name=m.name;
            this.conductivity=m.conductivity;
            this.conduttance=m.conduttance;
            this.tickness=m.tickness;
            this.conductivityEquivalent=m.conductivityEquivalent;
            this.density=m.density;
            this.specificheat=m.specificheat;
            this.hygroscopicresistnacefactor=m.hygroscopicresistnacefactor;
            this.vaporpermeability=m.vaporpermeability;
            this.dynamicstiffness = m.dynamicstiffness;
        }
        /// <summary>
        /// costruttore vuoto
        /// </summary>
        public Materiale() 
        {
            vaporpermeability = new double[2];
            
        }
        /// <summary>
        /// tipologia del materiale
        /// </summary>
        public string TypologyDescription
        {
            get 
            {
                return EnumHelper.GetDescription(this.typology);
            }
        }

        public double TermicalResistance
        {
            get
            {
                return UNI.Energy.UniEnIso6946.Rtot(this);
            }
        }
        /// <summary>
        /// Carica il materiale dall'xml
        /// </summary>
        /// <param name="node">Nodo XML</param>
        /// <returns>Materiale</returns>
        public static Materiale getByXML(XmlNode node)
        {
            Materiale m = new Materiale();
            m.name = node.SelectSingleNode("Name").InnerText;
            m.density = double.Parse(node.SelectSingleNode("Density").InnerText.Replace(".",","));
            m.conductivity = double.Parse( node.SelectSingleNode("Conductivity").InnerText.Replace(".", ","));
            m.specificheat =  double.Parse(node.SelectSingleNode("SpecificHeat").InnerText.Replace(".", ","));
            m.hygroscopicresistnacefactor =  double.Parse(node.SelectSingleNode("HygroscopicResistnaceFactor").InnerText.Replace(".", ","));
            m.conduttance =  double.Parse(node.SelectSingleNode("Conduttance").InnerText.Replace(".", ","));
            m.tickness =  double.Parse(node.SelectSingleNode("Tickness").InnerText.Replace(".", ","));
            m.typology = Materiale.typology_material.generic;
            //m.VaporPermeabilityMin =  double.Parse(node.SelectSingleNode("VaporPermeabilityMin").InnerText.Replace(".", ","));
            //m.VaporPermeabilityMax =  double.Parse(node.SelectSingleNode("VaporPermeabilityMax").InnerText.Replace(".", ","));
            m.conductivityEquivalent = node.SelectSingleNode("ConductivityEquivalent").InnerText == "false" ? false : true;
            m.dynamicstiffness =  double.Parse(node.SelectSingleNode("DynamicStiffness").InnerText.Replace(".", ","));

            //m.vaporpermeability[0] =  double.Parse(node.SelectSingleNode("VaporPermeability").ChildNodes[0].InnerText.Replace(".", ","));
            //m.vaporpermeability[1] =  double.Parse(node.SelectSingleNode("VaporPermeability").ChildNodes[1].InnerText.Replace(".", ","));
            return m;
        }
    }
}
